/*
 * RequestHandler.cpp
 *
 *  Created on: 29/11/2014
 *      Author: gustavo
 */

#include "RequestHandler.h"
#include <string.h>
#include <sstream>
#include <DBGestor.h>

RequestHandler::RequestHandler() {
	this->dbGestor = DBGestor::getInstance();
	log = Logger::getInstance();
}

RequestHandler::~RequestHandler() {
	delete this->dbGestor;
}

persona_st RequestHandler::parsePerson(const char* message) {
	log->log(INFO, "[RequestHandler] Parseo persona recibida en el mensaje " );
	persona_st persona;
	persona_st *msg = (persona_st*)message;
	std::stringstream s;

	memcpy(persona.nombre,    msg->nombre,    sizeof(persona_st::nombre));
	memcpy(persona.direccion, msg->direccion, sizeof(persona_st::direccion));
	memcpy(persona.telefono,  msg->telefono,  sizeof(persona_st::telefono));

	s <<" n:" << persona.nombre <<" d:" << persona.direccion <<" t:" <<persona.telefono;
	log->log(INFO, "[RequestHandler] Parseo completado: " + s.str() );

	return persona;
}

std::string RequestHandler::parseName(const char* message) {
	log->log(INFO, "[RequestHandler] Paseo nombre recibido en el mensaje");
	char name[sizeof(persona_st::nombre)];
	memset(name, 0, sizeof(persona_st::nombre));
	memcpy(name, message, sizeof(persona_st::nombre));

	log->log(INFO, "[RequestHandler] Parseando nombre: " + std::string(name) );

	return std::string(name);
}

mensaje_st RequestHandler::processInsert(mensaje_st* message) {
	log->log(INFO, "[RequestHandler] Operacion insert");
	mensaje_st replyMessage;
	memset(&replyMessage, 0, sizeof(replyMessage));

	replyMessage.mtype = message->pidSender;
	replyMessage.pidSender = 1;
	replyMessage.idOperation = SUCCESSFULL_RESPONSE_WITHOUT_TEXT;

	persona_st person = parsePerson(message->messageText);
	try {
		log->log(INFO, "[RequestHandler] Procesando el insert en la bd");
		this->dbGestor->add(person);
		log->log(INFO, "[RequestHandler] Inser realizado de forma exitosa");

	} catch (const char* message) {
		std::string errorMsg(message);
		log->log(ERROR, "[RequestHandler] " + errorMsg);
		replyMessage.idOperation = ERROR_RESPONSE;
		memcpy(replyMessage.messageText, message, sizeof(persona_st));
	}
	return replyMessage;
}

mensaje_st RequestHandler::processRemove(mensaje_st* message) {
	log->log(INFO, "[RequestHandler] Operacion remove");
	mensaje_st replyMessage;
	memset(&replyMessage, 0, sizeof(replyMessage));

	replyMessage.mtype = message->pidSender;
	replyMessage.pidSender = 1;
	replyMessage.idOperation = SUCCESSFULL_RESPONSE_WITHOUT_TEXT;

	std::string person = parseName(message->messageText);
	try {
		log->log(INFO, "[RequestHandler] Procesando remove en la bd");
		this->dbGestor->remove(person);
		log->log(INFO, "[RequestHandler] Remove realizado de forma exitosa");
	} catch (const char* message) {
		std::string errorMsg(message);
		log->log(ERROR, "[RequestHandler] " + errorMsg);
		replyMessage.idOperation = ERROR_RESPONSE;
		memcpy(replyMessage.messageText, message, sizeof(persona_st));
	}
	return replyMessage;
}

mensaje_st RequestHandler::processUpdate(mensaje_st* message) {
	log->log(INFO, "[RequestHandler] Operacion update");
	mensaje_st replyMessage;
	memset(&replyMessage, 0, sizeof(replyMessage));

	replyMessage.mtype = message->pidSender;
	replyMessage.pidSender = 1;
	replyMessage.idOperation = SUCCESSFULL_RESPONSE_WITHOUT_TEXT;

	persona_st person = parsePerson(message->messageText);
	try {
		log->log(INFO, "[RequestHandler] Procesando update en la bd");
		this->dbGestor->update(person);
		log->log(INFO, "[RequestHandler] Update realizado de forma exitosa");
	} catch (const char* message) {
		std::string errorMsg(message);
		log->log(ERROR, "[RequestHandler] " + errorMsg);
		replyMessage.idOperation = ERROR_RESPONSE;
		memcpy(replyMessage.messageText, message, sizeof(persona_st));
	}
	return replyMessage;
}

mensaje_st RequestHandler::processConsult(mensaje_st* message) {
	log->log(INFO, "[RequestHandler] Operacion consulta");
	mensaje_st replyMessage;
	memset(&replyMessage, 0, sizeof(replyMessage));

	replyMessage.mtype = message->pidSender;
	replyMessage.pidSender = 1;
	replyMessage.idOperation = SUCCESSFULL_RESPONSE_CONSULT;

	std::string personName = parseName(message->messageText);
	try {
		log->log(INFO, "[RequestHandler] Procesando consult en la bd");
		persona_st person = this->dbGestor->consult(personName);
		persona_st *p_persona = (persona_st*)replyMessage.messageText;
		log->log(INFO, "[RequestHandler] Consulta realizada de forma exitosa");
		memcpy(p_persona->nombre, person.nombre, sizeof(person.nombre));
		memcpy(p_persona->direccion, person.direccion, sizeof(person.direccion));
		memcpy(p_persona->telefono, person.telefono, sizeof(person.telefono));
	} catch (const char* message) {
		std::string errorMsg(message);
		log->log(ERROR, "[RequestHandler] " + errorMsg);
		replyMessage.idOperation = sizeof(persona_st::telefono);
		memcpy(replyMessage.messageText, message, sizeof(persona_st));
	}
	return replyMessage;
}

mensaje_st RequestHandler::proccessMessage(mensaje_st* message) {

	short operationId = message->idOperation;

	switch (operationId) {
		case ADD: {
			log->log(INFO, "[RequestHandler] Mensaje insert");
			return this->processInsert(message);
		}
		case REMOVE: {
			log->log(INFO, "[RequestHandler] Mensaje remover");
			return processRemove(message);
		}
		case UPDATE: {
			log->log(INFO, "[RequestHandler] Mensaje update");
			return processUpdate(message);
		}
		case CONSULT: {
			log->log(INFO, "[RequestHandler] Mensaje consultar");
			return processConsult(message);
		}
		default: {
			mensaje_st men = {0};
			log->log(ERROR, "[RequestHandler] Mensaje no identificado");
			return men;
		}
	}

	return *message;
}
